package com.icloud.cer.rest.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.icloud.cer.rest.Constants;
import com.icloud.cer.rest.web.bean.ServerConfig;

public final class XMLUtils {
	private static Log log=LogFactory.getLog(XMLUtils.class);
	//ServerInfo.xml
	public static ServerConfig getServerConfig3(InputStream inputStream) {
		ServerConfig sc = new ServerConfig();
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
        DocumentBuilder builder;
		try {
			builder = factory.newDocumentBuilder();
			Document document = builder.parse(inputStream);  
			Element element = document.getDocumentElement();
			NodeList serverNodes = element.getElementsByTagName("server");
			for (int i = 0; i < serverNodes.getLength(); i++) {
				Element bookElement = (Element) serverNodes.item(i);
				sc.setId(bookElement.getAttribute("id"));
				NodeList childNodes = bookElement.getChildNodes();
				// System.out.println("*****"+childNodes.getLength());
				for (int j = 0; j < childNodes.getLength(); j++) {
					if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {
						if ("Id".equals(childNodes.item(j).getNodeName())) {
							sc.setId(childNodes.item(j).getFirstChild().getNodeValue());
						} else if ("Name".equals(childNodes.item(j).getNodeName())) {
							sc.setName(childNodes.item(j).getFirstChild().getNodeValue());
						} else if ("IP".equals(childNodes.item(j).getNodeName())) {
							sc.setIp(childNodes.item(j).getFirstChild().getNodeValue());
						} else if ("Enabled".equals(childNodes.item(j).getNodeName())) {
							sc.setEnabled(Boolean.valueOf(childNodes.item(j).getFirstChild().getNodeValue()));
						}
					}
				}// end for j
				return sc;
			}
		} catch (ParserConfigurationException e) {
			log.error("", e);
		} catch (SAXException e) {
			log.error("", e);
		} catch (IOException e) {
			log.error("", e);
		}  
        return sc;
	}
	
	public static ServerConfig getServerConfig(InputStream inputStream) {
		ServerConfig sc = new ServerConfig();
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
        DocumentBuilder builder;
		try {
			builder = factory.newDocumentBuilder();
			Document document = builder.parse(inputStream);  
			Element element = document.getDocumentElement();
			NodeList serverNodes = element.getChildNodes();
			for (int i = 0; i < serverNodes.getLength(); i++) {
				Node node = serverNodes.item(i);
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					if ("Id".equals(node.getNodeName())) {
						sc.setId(node.getTextContent());
					} else if ("Name".equals(node.getNodeName())) {
						sc.setName(node.getTextContent());
					} else if ("IP".equals(node.getNodeName())) {
						sc.setIp(node.getTextContent());
					} else if ("Enabled".equals(node.getNodeName())) {
						sc.setEnabled(Boolean.valueOf(node.getTextContent()));
					}
				}
			}
			return sc;
		} catch (ParserConfigurationException e) {
			log.error("", e);
		} catch (SAXException e) {
			log.error("", e);
		} catch (IOException e) {
			log.error("", e);
		}  
        return sc;
	}
	
	public static List<String> getBlackIpList(InputStream inputStream) {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
        DocumentBuilder builder;
        List<String> blackIpList = new ArrayList<String>();
		try {
			builder = factory.newDocumentBuilder();
			Document document = builder.parse(inputStream);  
			Element element = document.getDocumentElement();
			NodeList serverNodes = element.getChildNodes();
			for (int i = 0; i < serverNodes.getLength(); i++) {
				Node node = serverNodes.item(i);
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					if ("IP".equals(node.getNodeName())) {
						blackIpList.add(node.getTextContent());
					}
				}
			}
			return blackIpList;
		} catch (ParserConfigurationException e) {
			log.error("", e);
		} catch (SAXException e) {
			log.error("", e);
		} catch (IOException e) {
			log.error("", e);
		}
		log.warn("not found black ip config.");
		return blackIpList;
	}
	
	public static void addBlackIp(String fileName, String ip){
		InputStream inputStream = XMLUtils.class.getClassLoader().getResourceAsStream(fileName);
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder;
		try {
			builder = factory.newDocumentBuilder();
			Document document = builder.parse(inputStream); 
			Node node = document.getFirstChild();;
			Element eltName=document.createElement("IP"); 
			eltName.setTextContent(ip);
			node.appendChild(eltName);
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			URL url = XMLUtils.class.getClassLoader().getResource(fileName);
			File f = new File(url.getPath());
			FileOutputStream fos = new FileOutputStream(f);
			nodeToXML(document, os, Constants.CHARSET.name());
			os.writeTo(fos);
			fos.close();
			log.warn("add " + ip + " to black ip list.");
		} catch (ParserConfigurationException e) {
			log.error("", e);
		} catch (SAXException e) {
			log.error("", e);
		} catch (IOException e) {
			log.error("", e);
		}  
	}
	
	public static void nodeToXML(Node node,OutputStream os,String charSet) {
		try {
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer t = null;
			t = tf.newTransformer();
			if(node instanceof Document){
				t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
			}else{
				t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
			}
			t.setOutputProperty(OutputKeys.INDENT, "yes");
			tf.setAttribute("indent-number", 4);	
			t.setOutputProperty(OutputKeys.METHOD, "xml");
			t.setOutputProperty(OutputKeys.ENCODING, charSet);

			DOMSource doms = new DOMSource(node);
			StreamResult sr = new StreamResult(os);
			t.transform(doms, sr);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
